package nz.ac.massey.doi_information_extractor.gui;

import java.awt.Component;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.ButtonGroup;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JRadioButton;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.LayoutStyle;
import javax.swing.text.DefaultFormatterFactory;

import nz.ac.massey.doi_information_extractor.data.PortNumberFormatter;
import nz.ac.massey.doi_information_extractor.data.Settings;


@SuppressWarnings("serial")
public class SettingsDialog extends JDialog implements ActionListener{

    private static SettingsDialog dialog;
    private JButton applyButton, cancelButton, changeDatabaseButton;
    private Settings currentSettings;
	private static Settings newSettings;
    private JRadioButton noProxyRadioButton, manualProxyRadioButton, authenticationRadioButton;
    private JTextField proxyTextField, databasePathTextField, authenticationIdTextField;
    private JFormattedTextField portTextField;
    private JPasswordField authenticationPwrdTextField;


    public static Settings showDialog(Component frameComp, Settings settings){
		Frame frame = JOptionPane.getFrameForComponent(frameComp);

		dialog = new SettingsDialog(frame, settings);

		dialog.setVisible(true);
		dialog = null;

    	return newSettings;
    }

    public SettingsDialog(Frame frame, Settings currentSettings){
    	super(frame, "Settings", true);

    	this.currentSettings = currentSettings;

    	init();

    	if(!currentSettings.getProxy().equals("")){
    		manualProxyRadioButton.setSelected(true);
    		proxyTextField.setText(currentSettings.getProxy());
    		portTextField.setText(Integer.toString(currentSettings.getPort()));
    	}else{
    		noProxyRadioButton.setSelected(true);
    		proxyTextField.setEditable(false);
    		proxyTextField.setEnabled(false);
    		portTextField.setEditable(false);
    		portTextField.setEnabled(false);
    		authenticationRadioButton.setEnabled(false);
    	}

    	if(!currentSettings.getUserId().equals("")){
    		authenticationIdTextField.setText(currentSettings.getUserId());
    		authenticationPwrdTextField.setText(currentSettings.getUserPassword());
    		authenticationRadioButton.setSelected(true);
    	}else{
    		authenticationIdTextField.setEditable(false);
    		authenticationIdTextField.setEnabled(false);
    		authenticationPwrdTextField.setEditable(false);
    		authenticationPwrdTextField.setEnabled(false);
    	}

    	if(currentSettings.getDatabasePath() != null)
    		databasePathTextField.setText(currentSettings.getDatabasePath());
    }

	private void init(){
		JPanel internetPanel = new JPanel();
		noProxyRadioButton = new JRadioButton("No Proxy");
		noProxyRadioButton.addActionListener(this);

		manualProxyRadioButton = new JRadioButton("Manual Proxy Configuration");
		manualProxyRadioButton.addActionListener(this);

		ButtonGroup proxyGroup = new ButtonGroup();
		proxyGroup.add(noProxyRadioButton);
		proxyGroup.add(manualProxyRadioButton);

		JLabel proxyLabel = new JLabel("HTTP Proxy:");
		JLabel portLabel = new JLabel("Port:");

		proxyTextField = new JTextField();

		PortNumberFormatter fmt = new PortNumberFormatter();
		fmt.setValueClass( Integer.class );
		portTextField = new JFormattedTextField(new DefaultFormatterFactory( fmt ));

		JLabel userLabel = new JLabel("User:");
		JLabel passwordLabel = new JLabel("Password:");

		authenticationRadioButton = new JRadioButton("Requires Authentication");
		authenticationRadioButton.addActionListener(this);

		authenticationIdTextField = new JTextField();
		authenticationPwrdTextField = new JPasswordField();

        GroupLayout internetPanelLayout = new GroupLayout(internetPanel);
        internetPanel.setLayout(internetPanelLayout);
        internetPanelLayout.setHorizontalGroup(
            internetPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(internetPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(noProxyRadioButton)
                .addContainerGap(222, Short.MAX_VALUE))
            .addGroup(internetPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(internetPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(manualProxyRadioButton)
                    .addGroup(internetPanelLayout.createSequentialGroup()
                        .addGap(21, 21, 21)
                        .addGroup(internetPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                            .addComponent(proxyLabel)
                            .addComponent(portLabel)
                            .addComponent(authenticationRadioButton)
                            .addGroup(internetPanelLayout.createSequentialGroup()
                                .addGap(21, 21, 21)
                                .addGroup(internetPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
                                    .addComponent(userLabel)
                                    .addComponent(passwordLabel)
                                    .addComponent(authenticationPwrdTextField, GroupLayout.DEFAULT_SIZE, 232, Short.MAX_VALUE)
                                    .addComponent(authenticationIdTextField)))
                            .addGroup(internetPanelLayout.createParallelGroup(GroupLayout.Alignment.TRAILING, false)
                                .addComponent(portTextField, GroupLayout.Alignment.LEADING)
                                .addComponent(proxyTextField, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 254, Short.MAX_VALUE)))
                        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                .addContainerGap())
        );
        internetPanelLayout.setVerticalGroup(
            internetPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(internetPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(noProxyRadioButton)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(manualProxyRadioButton)
                .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(proxyLabel)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(proxyTextField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(portLabel)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(portTextField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(authenticationRadioButton)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(userLabel)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(authenticationIdTextField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(passwordLabel)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(authenticationPwrdTextField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

		JPanel databasePanel = new JPanel();

		databasePathTextField = new JTextField();
		databasePathTextField.setEnabled(false);
		databasePathTextField.setEditable(false);

		changeDatabaseButton = new JButton("Change Database");
		changeDatabaseButton.addActionListener(this);

		JLabel databaseLabel = new JLabel("Current Database");

		GroupLayout databasePanelLayout = new GroupLayout(databasePanel);
		databasePanel.setLayout(databasePanelLayout);
		databasePanelLayout
				.setHorizontalGroup(databasePanelLayout
						.createParallelGroup(GroupLayout.Alignment.LEADING)
						.addGroup(
								databasePanelLayout
										.createSequentialGroup()
										.addContainerGap()
										.addGroup(
												databasePanelLayout
														.createParallelGroup(
																GroupLayout.Alignment.LEADING)
														.addComponent(
																databaseLabel)
														.addComponent(
																databasePathTextField,
																GroupLayout.DEFAULT_SIZE,
																244,
																Short.MAX_VALUE)
														.addComponent(
																changeDatabaseButton))
										.addContainerGap()));
		databasePanelLayout.setVerticalGroup(databasePanelLayout
				.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(
						databasePanelLayout
								.createSequentialGroup()
								.addContainerGap()
								.addComponent(databaseLabel)
								.addPreferredGap(
										LayoutStyle.ComponentPlacement.RELATED)
								.addComponent(databasePathTextField,
										GroupLayout.PREFERRED_SIZE,
										GroupLayout.DEFAULT_SIZE,
										GroupLayout.PREFERRED_SIZE)
								.addPreferredGap(
										LayoutStyle.ComponentPlacement.RELATED)
								.addComponent(changeDatabaseButton)
								.addContainerGap(147, Short.MAX_VALUE)));


        JTabbedPane tabbedPane = new JTabbedPane();
		tabbedPane.add("Internet", internetPanel);
		tabbedPane.add("Database", databasePanel);

		applyButton = new JButton();
		applyButton.setText("Apply");
		applyButton.addActionListener(this);

		cancelButton = new JButton();
		cancelButton.setText("Cancel");
		cancelButton.addActionListener(this);

		JPanel mainPanel = new JPanel();

		mainPanel.add(applyButton);
		mainPanel.add(cancelButton);

		mainPanel.add(tabbedPane);

        GroupLayout mainPanelLayout = new GroupLayout(mainPanel);
        mainPanel.setLayout(mainPanelLayout);
        mainPanelLayout.setHorizontalGroup(
            mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(mainPanelLayout.createSequentialGroup()
                .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addGroup(GroupLayout.Alignment.TRAILING, mainPanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(applyButton, GroupLayout.PREFERRED_SIZE, 93, GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(cancelButton, GroupLayout.PREFERRED_SIZE, 86, GroupLayout.PREFERRED_SIZE))
                    .addGroup(mainPanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(tabbedPane, GroupLayout.PREFERRED_SIZE, 302, GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        mainPanelLayout.setVerticalGroup(
            mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(mainPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(tabbedPane, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(cancelButton)
                    .addComponent(applyButton))
                .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

		getContentPane().add(mainPanel);

		pack();
	}

	@Override
	public void actionPerformed(ActionEvent event) {
		if(event.getSource() == applyButton){
			if(noProxyRadioButton.isSelected()){
				newSettings = new Settings(databasePathTextField.getText());
			}else{

				String proxyAddress;
				String databasePath;
				int portNumber;

				try{
					proxyAddress = proxyTextField.getText();
				}catch(Exception ex){
					JOptionPane.showMessageDialog(this, "No proxy entered");
					return;
				}

				try{
					portNumber = Integer.parseInt(portTextField.getText());
				}catch(Exception ex){
					JOptionPane.showMessageDialog(this, "No port number entered");
					return;
				}

				try{
					databasePath = databasePathTextField.getText();
				}catch(Exception ex){
					JOptionPane.showMessageDialog(this, "No database selected");
					return;
				}


				if(authenticationRadioButton.isSelected()){
					String userId;
					String userPassword;

					try{
						userId = authenticationIdTextField.getText();
					}catch(Exception ex){
						JOptionPane.showMessageDialog(this, "No user id entered");
						return;
					}

					try{
						userPassword = authenticationPwrdTextField.getPassword().toString();
					}catch(Exception ex){
						userPassword ="";
					}

					newSettings = new Settings(databasePath, portNumber, proxyAddress, userId, userPassword);
				}else{
					newSettings = new Settings(databasePath, portNumber, proxyAddress);
				}
			}

			dialog.setVisible(false);
		}else if(event.getSource() == cancelButton){
			newSettings = currentSettings;
			dialog.setVisible(false);
		}else if(event.getSource() == changeDatabaseButton){

			JFileChooser dbFileChooser = new JFileChooser();

			dbFileChooser.setDialogTitle("Choose Database");
			dbFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
			dbFileChooser.removeChoosableFileFilter(dbFileChooser.getFileFilter());
			dbFileChooser.setFileFilter(new DbFileFilter());

			if(dbFileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION){
	            File file = dbFileChooser.getSelectedFile();
	            databasePathTextField.setText(file.getAbsolutePath());
			}

		}else if(event.getSource() == noProxyRadioButton ){
			proxyTextField.setEnabled(false);
			proxyTextField.setEditable(false);

			portTextField.setEnabled(false);
			portTextField.setEditable(false);

			authenticationRadioButton.setEnabled(false);

    		authenticationIdTextField.setEditable(false);
    		authenticationIdTextField.setEnabled(false);
    		authenticationPwrdTextField.setEditable(false);
    		authenticationPwrdTextField.setEnabled(false);
		}else if(event.getSource() == manualProxyRadioButton){
			proxyTextField.setEnabled(true);
			proxyTextField.setEditable(true);

			portTextField.setEnabled(true);
			portTextField.setEditable(true);

			authenticationRadioButton.setEnabled(true);

			if (authenticationRadioButton.isSelected()) {
				authenticationIdTextField.setEditable(true);
				authenticationIdTextField.setEnabled(true);
				authenticationPwrdTextField.setEditable(true);
				authenticationPwrdTextField.setEnabled(true);
			}


		}else if(event.getSource() == authenticationRadioButton){
			if(authenticationRadioButton.isSelected()){
	    		authenticationIdTextField.setEditable(true);
	    		authenticationIdTextField.setEnabled(true);
	    		authenticationPwrdTextField.setEditable(true);
	    		authenticationPwrdTextField.setEnabled(true);
			}else{
	    		authenticationIdTextField.setEditable(false);
	    		authenticationIdTextField.setEnabled(false);
	    		authenticationPwrdTextField.setEditable(false);
	    		authenticationPwrdTextField.setEnabled(false);
			}
		}
	}
}
